#include <iostream>
#include <cstring>
#include <arpa/inet.h> // Linux/macOS
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
// Windows 需要 winsock2.h

int main()
{
    //创建TCP socket
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock == -1)
    {
        std::cerr << "创建 socket 失败: " << strerror(errno) << std::endl;
        return -1;
    }

    //配置服务器地址
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(5020); //连接5020端口
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    //连接到服务器
    std::cout << "正在连接到服务器...\n";
    if(connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
    {
        std::cerr << "连接服务器失败\n";
        close(sock);
        return -1;
    }

    std::cout << "已连接到Modbus TCP 服务器\n";

    // 手动构造一个读保持寄存器请求
    uint8_t request[12];

    // Transaction ID (2字节)
    request[0] = 0x00;
    request[1] = 0x01;

    // Protocol ID (2字节，固定为0)
    request[2] = 0x00;
    request[3] = 0x00;

    // Length (2字节，后续6字节)
    request[4] = 0x00;
    request[5] = 0x06;

    // Unit ID
    request[6] = 0x01;

    // Function Code: 0x03 (读保持寄存器)
    request[7] = 0x03;

    // 起始地址: 0
    request[8] = 0x00;
    request[9] = 0x00;

    // 寄存器数量: 3
    request[10] = 0x00;
    request[11] = 0x03;

    // 接下来你可以用 socket 发送这个 request
    // 并接收响应，手动解析返回数据

    std::cout << "已构造 Modbus TCP 请求报文\n";
    for (int i = 0; i < 12; i++)
    {
        printf("%02X ", request[i]);
    }
    printf("\n");

    //发送请求
    ssize_t bytes_sent = send(sock, request, sizeof(request), 0);
    if (bytes_sent == -1)
    {
        std::cerr << "发送请求失败\n";
        close(sock);
        return -1;
    }
    std::cout << "已发送 " << bytes_sent << " 字节请求报文\n" << std::endl;

    //接收响应
    uint8_t response[256];
    std::cout << "正在接收响应...\n";
    ssize_t bytes_received = recv(sock, response, sizeof(response), 0);
    if(bytes_received == -1)
    {
        std::cerr << "接收响应失败: " << strerror(errno) << std::endl;
        close(sock);
        return -1;
    }

    if(bytes_received == 0)
    {
        std::cout << "连接已关闭，未接收到数据" << std::endl;
        close(sock);
        return -1;
    }

    std::cout << "接收的相应报文： ";
    for (int i = 0; i < bytes_received; i++)
    {
        printf("%02X ", response[i]);
    }
    printf("\n");

    //解析响应
    if(bytes_received >= 9)
    {
        uint16_t transaction_id = (response[0] << 8) | response[1];
        uint16_t protocol_id = (response[2] << 8) | response[3];
        uint16_t length = (response[4] << 8) | response[5];
        uint8_t unit_id = response[6];
        uint8_t function_code = response[7];
        uint8_t byte_count = response[8];

        std::cout << "\n=== 响应解析 ===\n";
        std::cout << "Transaction ID: 0x" << std::hex << transaction_id << std::dec << "\n";
        std::cout << "Protocol ID: 0x" << std::hex << protocol_id << std::dec << "\n";
        std::cout << "Length: " << length << "\n";
        std::cout << "Unit ID: " << (int)unit_id << "\n";
        std::cout << "Function Code: 0x" << std::hex << (int)function_code << std::dec << "\n";
        std::cout << "Byte Count: " << (int)byte_count << "\n";

        std::cout << "寄存器值: ";
        for (int i = 0; i < byte_count; i += 2)
        {
            uint16_t reg_value = (response[9 + i] << 8) | response[9 + i + 1];
            std::cout << reg_value << " ";
        }
        std::cout << "\n";
    }
    else
    {
        std::cout << "响应数据长度不足，无法解析\n";
    }

    //构造写单个寄存器请求（写寄存器地址0值为500）
    uint8_t write_request[12];

    // Transaction ID
    write_request[0] = 0x00;
    write_request[1] = 0x02;

    // Protocol ID
    write_request[2] = 0x00;
    write_request[3] = 0x00;

    // Length
    write_request[4] = 0x00;
    write_request[5] = 0x06;

    // Unit ID
    write_request[6] = 0x01;

    // Function Code: 0x06 (写单个寄存器)
    write_request[7] = 0x06;

    // 寄存器地址: 0
    write_request[8] = 0x00;
    write_request[9] = 0x00;

    // 寄存器值: 500(0x01F4)
    write_request[10] = 0x01;
    write_request[11] = 0xF4;

    std::cout << "已构造 Modbus TCP 写单个寄存器请求报文\n";
    for (size_t i = 0; i < 12; i++)
    {
        std::cout << std::hex << (int)write_request[i] << " ";
    }
    std::cout << std::endl;

    //发送写请求
    bytes_sent = send(sock, write_request, sizeof(write_request), 0);
    if(bytes_sent == -1)
    {
        std::cerr << "发送验证请求失败： " << strerror(errno) << std::endl;
        close(sock);
        return -1;
    }
    std::cout << "已发送 " << bytes_sent << " 字节验证请求报文" << std::endl;

    //接收验证响应
    std::cout << "正在接收验证响应...\n";
    bytes_received = recv(sock, response, sizeof(response), 0);
    if(bytes_received == -1)
    {
        std::cerr << "接收验证响应失败： " << strerror(errno) << std::endl;
        close(sock);
        return -1;
    }

    if(bytes_received == 0)
    {
        std::cout << "连接已关闭，未接收到数据" << std::endl;
        close(sock);
        return -1;
    }

    std::cout << "接收的验证响应报文： ";
    for (int i = 0; i < bytes_received; i++)
    {
        printf("%02X ", response[i]);
    }
    printf("\n");

    if (bytes_received >= 9)
    {
        uint8_t byte_count = response[8];
        std::cout << "验证寄存器值: ";
        for (int i = 0; i < byte_count; i += 2)
        {
            uint16_t reg_value = (response[9 + i] << 8) | response[9 + i + 1];
            std::cout << reg_value << " ";
        }
        std::cout << "\n";
    }

    //关闭连接
    close(sock);
    std::cout << "已关闭连接" << std::endl;
    return 0;
}